import json
import re
import requests
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ValidationError
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.shortcuts import render, redirect
from django import forms
# Create your views here.
from api_test.models import UserInfo, DB_tucao, DB_Gateway, DB_project, DB_apis, DB_apis_log, DB_cases, DB_step, \
    Interface, Scene, DB_project_header, DB_host, DB_project_host, DB_login, DB_global_data
import random

from api_test.utils.fd_save import FidToSave
from api_test.view_tools import Cmp_json, cj


def mobile_validate(value):
    mobile_re = re.compile(r"^13[0-9]{9}$")
    if not mobile_re.match(value):
        raise ValidationError("手机号码格式错误")


# 做一个公共的字典，然后每个函数之后都默认加上这个字典。
def globaldict(request):
    userimg = str(request.session["user"]) + '.png'
    res = {"username": request.session["user"], "userimg": userimg}
    return res


class RegisterForm(forms.Form):
    username = forms.CharField(
        max_length=16,

        label='用户名',
        widget=forms.widgets.TextInput(attrs={"class": "username", "placeholder": "用户名"}),
        error_messages={
            "required": "用户名不能为空",

            "max_length": "用户名不能大于16位",
        }
    )

    password = forms.CharField(
        max_length=16,
        min_length=6,
        label='密码',
        widget=forms.widgets.PasswordInput(attrs={"class": "password", "placeholder": "密码"}),
        error_messages={
            "required": '密码不能为空',
            "max_length": "密码不能大于16位",
            "min_length": "密码不能小于6位",
        },

    )
    r_password = forms.CharField(
        max_length=16,
        min_length=6,
        label='确认密码',
        widget=forms.widgets.PasswordInput(attrs={"class": "password", "placeholder": "确认密码"}),
        error_messages={
            "required": '密码不能为空',
            "max_length": "密码不能大于16位",
            "min_length": "密码不能小于6位",
        },

    )
    email = forms.EmailField(
        label='邮箱',
        error_messages={"invalid": "邮箱格式不合法",
                        "required": "邮箱不能为空"},
        widget=forms.widgets.TextInput(attrs={"type": "email", "class": "email", "placeholder": "邮箱"})

    )
    telephone = forms.CharField(
        label='手机号码',
        validators=[mobile_validate, ],
        error_messages={"required": "手机号码不能为空"},
        widget=forms.widgets.TextInput(attrs={"placeholder": "手机号码", "id": "number", "class": "phone_number"})
    )

    def clean(self):
        value = self.cleaned_data
        password = value.get("password")
        r_password = value.get("r_password")
        if password == r_password:
            return value
        else:
            self.add_error("r_password", "两次密码不一致")


# 控制返回不同的页面和数据
def child(request, eid, oid, ooid):
    res = child_json(eid, oid, ooid)
    # print(f"当前登录的用户是{request.session['user']}")
    # print(f"eid 是{eid}")
    # print(f"res 是{res}")
    return render(request, eid, res)


# 控制不同页面返回的数据
def child_json(eid, oid='', ooid=''):
    res = {}
    if eid == 'gateway.html':
        data = DB_Gateway.objects.all()
        res = {"hrefs": data}
    elif eid == 'project_list.html':
        data = DB_project.objects.all()
        res = {"projects": data}
    elif eid == 'P_project_set.html':
        project = DB_project.objects.filter(id=oid)[0]
        res = {"project": project}
    elif eid == 'P_apis.html':
        project = DB_project.objects.filter(id=oid)[0]
        apis = DB_apis.objects.filter(project_id=oid)
        for i in apis:
            try:
                i.short_url = i.api_url.split('?')[0][:50]
            except:
                i.short_url = ''
        hosts = DB_host.objects.all()
        project_host = DB_project_host.objects.filter(project_id=oid)
        project_header = DB_project_header.objects.filter(project_id=oid)
        # print(f"project_header ==》{project_header}")
        res = {"project": project, "project_host": project_host, "hosts": hosts, "apis": apis,
               "project_header": project_header}

    elif eid == 'home.html':
        date = DB_Gateway.objects.all()
        home_log = DB_apis_log.objects.filter(user_id=oid)[::-1]
        hosts = DB_host.objects.all()

        user_projects = DB_project.objects.filter(user=oid)

        # print(f"user_projects====>>{user_projects}")

        # 个人数据看板

        # 个人数据看板
        count_project = len(user_projects)
        count_api = sum([len(DB_apis.objects.filter(project_id_id=i.id)) for i in user_projects])
        count_case = sum([len(DB_cases.objects.filter(project_id=i.id)) for i in user_projects])

        ziyuan_all = len(DB_project.objects.all()) + len(DB_apis.objects.all()) + len(DB_cases.objects.all())
        ziyuan_user = count_project + count_api + count_case
        ziyuan = ziyuan_user / ziyuan_all * 100

        new_res = {
            "count_project": count_project,
            "count_api": count_api,
            "count_case": count_case,
            "count_report": '',
            "ziyuan": ziyuan,
        }

        if ooid == '':
            res = {"hrefs": date, "home_log": home_log, "hosts": hosts, "user_projects": user_projects}
        else:
            log = DB_apis_log.objects.filter(id=ooid)[0]
            res = {"hrefs": date, "home_log": home_log, "log": log, "hosts": hosts, "user_projects": user_projects}

        res.update(new_res)
    elif eid == 'P_cases.html':
        # 这里要去大用例库区拿数据
        project = DB_project.objects.filter(id=oid)[0]
        Cases = DB_cases.objects.filter(project_id=oid)
        apis = DB_apis.objects.filter(project_id=oid)
        project_header = DB_project_header.objects.filter(project_id=oid)
        hosts = DB_host.objects.all()
        project_host = DB_project_host.objects.filter(project_id=oid)
        # print(f"Cases is {Cases}")
        res = {"Cases": Cases, "project_host": project_host, "hosts": hosts, "project": project, "apis": apis,
               "project_header": project_header}

    if eid == 'P_global_data.html':
        from django.contrib.auth.models import User
        project = DB_project.objects.filter(id=oid)[0]
        global_data = DB_global_data.objects.filter(user_id=project.user_id)
        res = {"project": project, "global_data": global_data}
    print(res)
    return res


# 登录
def login(request):
    if request.method == 'GET':
        print(request.POST)
        return render(request, 'login.html')
    else:
        username = request.POST.get("username")
        password = request.POST.get("password")
        user_obj = UserInfo.objects.filter(username=username,
                                           password=password).first()
        if user_obj:

            request.session["user"] = username
            return redirect('home')
        else:
            return render(request, 'login.html', {"error": "用户名密码错误"})


# 退出
def logout(request):
    request.session.flush()
    return redirect('login')


# 注册
def register(request):
    """
    注册
    :param request:
    :return:
    """
    if request.method == 'GET':
        register_obj = RegisterForm()
        return render(request, 'register.html', {"register_obj": register_obj})
    else:
        register_obj = RegisterForm(request.POST)
        if register_obj.is_valid():
            # print(register_obj.cleaned_data)
            register_obj.cleaned_data.pop("r_password")
            user_obj = UserInfo.objects.create(**register_obj.cleaned_data)

            return redirect("login")
        else:
            print(register_obj.errors)
            return render(request, 'register.html', {"register_obj": register_obj})


# 公共部分

def welcome(request):
    return render(request, 'welcome.html')


# 用例库
def case_list(request):
    return render(request, 'case_list.html')


# 主页

def home(request, log_id=''):
    print(f"访问的用户的id 是{request.session['user']}")
    return render(request, 'welcome.html',
                  {"whichHTML": "home.html", "oid": request.session['user'], "ooid": log_id, **globaldict(request)})


# 吐槽
def pei(request):
    tucao_text = request.GET.get("tucao_text")
    user = request.session.get("user")
    DB_tucao.objects.create(user=user, text=tucao_text)

    return HttpResponse("ok")


# 帮助
def api_help(request):
    return render(request, 'welcome.html', {"whichHTML": "help.html", "oid": "", **globaldict(request)})


# 传送门
def gateway(request):
    return render(request, 'welcome.html', {"whichHTML": 'gateway.html', "oid": "", **globaldict(request)})


# 小工具集合
def tools(request):
    return render(request, 'welcome.html', {"whichHTML": 'tools.html'})


# 生成随机数
def make_random(request):
    """
        生成随机字母与数字混合字符串
        :param length:
        :return:
        """
    length = request.GET.get("length")
    letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
               'v', 'w', 'x', 'y', 'z']
    random_list = []
    for _ in range(int(length)):
        random_list.append(random.randint(0, len(letters)) - 1)

    for i, v in enumerate(random_list):
        if i % 2 == 0:
            v %= 10
            random_list[i] = str(v)
            continue
        random_list[i] = letters[v]
    return HttpResponse(''.join(random_list))


# 项目列表
def project_list(request):
    return render(request, 'welcome.html', {"whichHTML": "project_list.html", "oid": "", **globaldict(request)})


# 删除项目
def delete_project(request):
    id = request.GET.get("id")
    DB_project.objects.filter(id=id).delete()
    DB_cases.objects.filter(project_id=id).delete()
    all_Case = DB_cases.objects.filter(project_id=id)
    for i in all_Case:
        DB_step.objects.filter(Case_id=i.id).delete()
        i.delete()
    return HttpResponse('')


# 新增项目
def add_project(request):
    project_name = request.GET.get("project_name")
    project_remark = request.GET.get("project_remark")
    user = request.session.get("user")
    user_id = UserInfo.objects.filter(username=user)[0].id
    DB_project.objects.create(name=project_name, remark=project_remark, user=user,user_id=user_id)
    return HttpResponse("")


# 进入接口库
def open_apis(request, id):
    # print(id)
    project_id = id
    return render(request, 'welcome.html', {"whichHTML": 'P_apis.html', "oid": project_id, **globaldict(request)})


# 进入用例库
def open_cases(request, id):
    project_id = id
    return render(request, 'welcome.html', {"whichHTML": 'P_cases.html', "oid": project_id, **globaldict(request)})


# 进入项目设置
def open_project_set(request, id):
    project_id = id
    return render(request, 'welcome.html',
                  {"whichHTML": 'P_project_set.html', "oid": project_id, **globaldict(request)})


# 保存项目设置
def save_project_set(request, id):
    name = request.GET.get("name")
    remark = request.GET.get("remark")
    other_user = request.GET.get("other_user")

    DB_project.objects.filter(id=id).update(name=name, remark=remark, other_user=other_user)

    return HttpResponse("")


# 新增接口
def project_api_add(request, Pid):
    project_id = Pid
    # DB_apis.objects.create(project_id=project_id, name="新增接口待调试")
    DB_apis.objects.create(project_id_id=project_id, name="新增接口待调试", api_method='none')
    return redirect('/apis/%s/' % project_id)


# 删除接口
def project_api_del(request, id):
    # 因为前端没有传project_id,这里可以通过接口的id来查询project_id
    project_id = DB_apis.objects.filter(id=id)[0].project_id_id

    DB_apis.objects.filter(id=id).delete()

    print(project_id)
    return redirect('/apis/%s' % project_id)


# 保存备注
def save_bz(request):
    text = request.GET.get("bz_value")
    api_id = request.GET.get("api_id")
    DB_apis.objects.filter(id=api_id).update(des=text)
    return HttpResponse("")


# 获取备注内容
def get_bz(request):
    api_id = request.GET.get("api_id")
    des = DB_apis.objects.filter(id=api_id)[0].des
    return HttpResponse(des)


# 保存调试接口数据.
def Api_save(request):
    api_id = request.GET.get("api_id")
    ts_method = request.GET.get("ts_method")
    ts_url = request.GET.get("ts_url")
    ts_header = request.GET.get("ts_header")
    ts_host = request.GET.get("ts_host")
    ts_body_method = request.GET.get("ts_body_method")
    # ts_api_body = request.GET.get("ts_api_body")
    ts_api_name = request.GET.get('ts_api_name')

    # 登录态
    ts_login = request.GET.get("ts_login")
    # 全局请求头
    ts_project_headers = request.GET.get('ts_project_headers')

    # print(f"ts_project_headers===>{ts_project_headers}")

    # 请求体页面点击保存处理
    if ts_body_method == '返回体':
        api = DB_apis.objects.filter(id=api_id)[0]
        ts_body_method = api.last_body_method
        ts_api_body = api.last_api_body
        #     如果用户是第一次打开调试界面，点击返回体子页面，再发送
        if ts_api_body in ["", None]:
            return HttpResponse("请先选择好请求头编码格式和请求体，再点击保存")
    else:
        ts_api_body = request.GET.get("ts_api_body")

    DB_apis.objects.filter(id=api_id).update(
        api_method=ts_method,
        api_url=ts_url,
        api_header=ts_header,
        api_host=ts_host,
        body_method=ts_body_method,
        api_body=ts_api_body,
        name=ts_api_name,

        api_login=ts_login,
        public_header=ts_project_headers,

    )

    return HttpResponse("success")


# 调试窗口获取数据
def get_api_data(request):
    api_id = request.GET.get("api_id")
    # values 必须要queryset 调用，返回一个queryset，里面都是字典形式
    api = DB_apis.objects.filter(id=api_id).values()[0]
    print(api)
    return JsonResponse(api, safe=False)


# 调试发送请求
def Api_send(request):
    api_id = request.GET.get("api_id")
    ts_method = request.GET.get("ts_method")
    ts_url = request.GET.get("ts_url")
    ts_header = request.GET.get("ts_header")
    ts_host = request.GET.get("ts_host")
    ts_body_method = request.GET.get("ts_body_method")
    # ts_api_body = request.GET.get("ts_api_body")
    ts_api_name = request.GET.get('ts_api_name')
    # 全局请求头
    ts_project_headers = request.GET.get('ts_project_headers')

    # 登录态
    ts_login = request.GET.get("ts_login")
    if ts_login == "yes":  # 说明要调用登录态接口了

        login_res = project_login_send_for_other(project_id=DB_apis.objects.filter(id=api_id)[0].project_id_id)
    else:
        login_res = {}
    print(f"login_res ====>{login_res}")

    #  处理域名host
    if ts_host[:4] == '全局域名':
        project_host_id = ts_host.split("-")[1]
        ts_host = DB_project_host.objects.filter(id=project_host_id)[0].host

        # print(f"全局域名是{ts_host}")

    # 解决 当用户点击返回体子页面时保存，出现请求体数据丢失问题
    if ts_body_method == '返回体':
        api = DB_apis.objects.filter(id=api_id)[0]
        ts_body_method = api.last_body_method
        ts_api_body = api.last_api_body
        #     如果用户是第一次打开调试界面，点击返回体子页面，再发送
        if ts_api_body in ["", None]:
            return HttpResponse("请先选择好请求头编码格式和请求体，再点击Send 发送")
    else:
        ts_api_body = request.GET.get("ts_api_body")
        api = DB_apis.objects.filter(id=api_id)
        api.update(last_api_body=ts_api_body, last_body_method=ts_body_method)

    # 发送请求获取返回值
    # 我们从前端拿到的是字符串，所以我们要在最开始获取的时候直接把header从字符串转变为字典。
    if ts_header == '':
        ts_header = '{}'
    try:
        header = json.loads(ts_header)
    except:
        return HttpResponse("请求头不符合json格式")

    try:
        for i in ts_project_headers.split(","):
            project_header = DB_project_header.objects.filter(id=i)[0]
            header[project_header.key] = project_header.value
    except:
        header = header

    print(f"header =====>>{header}")

    # 拼接url
    print(f"url 是 {ts_url}")
    if ts_url != None:
        if ts_host[-1] == '/' and ts_url[0] == '/':
            url = ts_host[:-1] + ts_url
        elif ts_host[-1] != '/' and ts_url[0] != '/':
            url = ts_host + "/" + ts_url
        else:
            url = ts_host + ts_url
    else:
        url = ts_host + '/'

        ## url插入    如果返回的是a 这里就报错了，所以加上字典判断！！！！过滤掉a
    if '?' not in url:
        url += '?'
        if type(login_res) == dict:
            for i in login_res.keys():
                url += i + '=' + login_res[i] + '&'
    else:  # 证明已经有参数了
        if type(login_res) == dict:
            for i in login_res.keys():
                url += '&' + i + '=' + login_res[i]

        # print(f"加了登录态的url======》{url}")

   ## header插入   如果返回的是a 这里就报错了，所以加上字典判断！！！！过滤掉a
    if type(login_res) == dict:
        header.update(login_res)
    # print(f"加了登录态的header======》{header}")





    try:
        if ts_body_method == 'none':
            if type(login_res) == dict:
                response = requests.request(ts_method.upper(), url, headers=header, data={})

            else:
                response = login_res.request(ts_method.upper(), url, headers=header, data={})

        #     paylaod是一个字典，把我们的字符串格式的二元列表转变成字符串。
        elif ts_body_method == 'form-data':
            files = []
            payload = {}
            for i in eval(ts_api_body):
                payload[i[0]] = i[1]

            if type(login_res) == dict:
                for i in login_res.keys():
                    payload[i] = login_res[i]
                response = requests.request(ts_method.upper(), url, headers=header, data=payload, files=files)
            else:
                response = login_res.request(ts_method.upper(), url, headers=header, data=payload, files=files)

        elif ts_body_method == 'x-www-form-urlencoded':
            header['Content-Type'] = 'application/x-www-form-urlencoded'
            payload = {}
            for i in eval(ts_api_body):
                payload[i[0]] = i[1]
            if type(login_res) == dict:
                for i in login_res.keys():
                    payload[i] = login_res[i]
                response = requests.request(ts_method.upper(), url, headers=header, data=payload)
            else:
                response = login_res.request(ts_method.upper(), url, headers=header, data=payload)


        else:
            if ts_body_method == 'Text':
                header["Content-Type"] = "text/plain"
            if ts_body_method == 'JavaScript':
                header["Content-Type"] = "text/plain"
            if ts_body_method == 'Json':
                # 登录态
                # 前端拿上来的是str，先转换成字典格式，添加完后再改回字符串
                ts_api_body = json.loads(ts_api_body)
                if type(login_res) == dict:
                    for i in login_res.keys():
                        ts_api_body[i] = login_res[i]
                    ts_api_body = json.dumps(ts_api_body)


                header['Content-Type'] = 'text/plain'
            if ts_body_method == 'Xml':
                header["Content-Type"] = "text/plain"
            if ts_body_method == 'Html':
                header["Content-Type"] = "text/plain"
            if type(login_res) == dict:
                response = requests.request(ts_method.upper(), url, headers=header, data=ts_api_body.encode('utf-8'))
            else:
                response = login_res.request(ts_method.upper(), url, headers=header, data=ts_api_body.encode('utf-8'))
        # 返回响应结果给前端
        response.encoding = 'utf-8'

        # 保存域名到全局域名表中
        DB_host.objects.update_or_create(host=ts_host)

        return HttpResponse(response.text)
    except Exception as e:
        return HttpResponse(str(e))


# 复制接口
def copy_api(request):
    api_id = request.GET.get("api_id")
    old_api = DB_apis.objects.filter(id=api_id)[0]
    DB_apis.objects.create(project_id_id=old_api.project_id_id,
                           name=old_api.name + '_副本',
                           api_method=old_api.api_method,
                           api_url=old_api.api_url,
                           api_header=old_api.api_header,
                           api_login=old_api.api_login,
                           api_host=old_api.api_host,
                           des=old_api.des,
                           body_method=old_api.body_method,
                           api_body=old_api.api_body,
                           result=old_api.result,
                           sign=old_api.sign,
                           file_key=old_api.file_key,
                           file_name=old_api.file_name,
                           public_header=old_api.public_header,
                           last_body_method=old_api.last_body_method,
                           last_api_body=old_api.last_api_body
                           )
    # 返回
    return HttpResponse('')


# 异常值请求
def error_request(request):
    api_id = request.GET.get('api_id')
    new_body = request.GET.get("new_body")
    span_text = request.GET.get('span_text')

    # print(f"new_body==>>{new_body}")

    api = DB_apis.objects.filter(id=api_id)[0]
    method = api.api_method
    url = api.api_url
    host = api.api_host
    header = api.api_header
    body_method = api.body_method

    if header == "":
        ts_header = '{}'

    try:
        header = json.loads(header)
    except:
        return HttpResponse("请求头不符合json格式")
        # 拼接url

    if url != None:
        if host[-1] == '/' and url[0] == '/':
            url = host[:-1] + url
        elif host[-1] != '/' and url[0] != '/':
            url = host + "/" + url
        else:
            url = host + url
    else:
        url = host + '/'

    try:
        if body_method == 'form-data':
            files = []
            payload = {}
            for i in eval(new_body):
                payload[i[0]] = i[1]
            response = requests.request(method.upper(), url, headers=header, data=payload, files=files)

        elif body_method == 'x-www-form-urlencoded':
            header["Content-Type"] = "x-www-form-urlencoded"
            payload = {}
            for i in eval(new_body):
                payload[i[0]] = i[1]
            response = requests.request(method.upper(), url, headers=header, data=payload)
        else:
            if body_method == 'Text':
                header["Content-Type"] = "text/plain"
            if body_method == 'JavaScript':
                header["Content-Type"] = "text/plain"
            if body_method == 'Json':
                header["Content-Type"] = "application/json"
            if body_method == 'Xml':
                header["Content-Type"] = "text/plain"
            if body_method == 'Html':
                header["Content-Type"] = "text/plain"
            response = requests.request(method.upper(), url, headers=header, data=new_body.encode("utf-8"))
        # 返回响应结果给前端
        response.encoding = 'utf-8'
        res_json = {"response": response.text, 'span_text': span_text}
        return HttpResponse(json.dumps(res_json), content_type='application/json')
    except:
        res_json = {"response": 'Sorry ！ 接口请求不通..', 'span_text': span_text}
        return HttpResponse(json.dumps(res_json), content_type='application/json')


# 首页调试
# 首页发送请求
def Api_send_home(request):
    # 提取所有数据
    print('qwe')
    ts_method = request.GET['ts_method']
    ts_url = request.GET['ts_url']
    ts_host = request.GET['ts_host']
    ts_header = request.GET['ts_header']
    ts_body_method = request.GET['ts_body_method']
    ts_api_body = request.GET['ts_api_body']
    # 发送请求获取返回值
    try:
        header = json.loads(ts_header) #处理header
    except:
        return HttpResponse('请求头不符合json格式！')

    user = request.session["user"]
    user_id = UserInfo.objects.filter(username=user)[0].id

    # 写入到数据库请求记录表中
    DB_apis_log.objects.create(user_id=user_id,
                               api_method=ts_method,
                               api_url=ts_url,
                               api_header=ts_header,
                               api_host=ts_host,
                               body_method=ts_body_method,
                               api_body=ts_api_body,
                               )

    # 拼接完整url
    if ts_host[-1] == '/' and ts_url[0] =='/': #都有/
        url = ts_host[:-1] + ts_url
    elif ts_host[-1] != '/' and ts_url[0] !='/': #都没有/
        url = ts_host+ '/' + ts_url
    else: #肯定有一个有/
        url = ts_host + ts_url
    try:
        if ts_body_method == 'none':
            response = requests.request(ts_method.upper(), url, headers=header, data={} )

        elif ts_body_method == 'form-data':
            files = []
            payload = {}
            for i in eval(ts_api_body):
                payload[i[0]] = i[1]
            response = requests.request(ts_method.upper(), url, headers=header, data=payload, files=files )

        elif ts_body_method == 'x-www-form-urlencoded':
            header['Content-Type'] = 'application/x-www-form-urlencoded'
            payload = {}
            for i in eval(ts_api_body):
                payload[i[0]] = i[1]
            response = requests.request(ts_method.upper(), url, headers=header, data=payload )

        else: #这时肯定是raw的五个子选项：
            if ts_body_method == 'Text':
                header['Content-Type'] = 'text/plain'

            if ts_body_method == 'JavaScript':
                header['Content-Type'] = 'text/plain'

            if ts_body_method == 'Json':
                header['Content-Type'] = 'text/plain'

            if ts_body_method == 'Html':
                header['Content-Type'] = 'text/plain'

            if ts_body_method == 'Xml':
                header['Content-Type'] = 'text/plain'
            response = requests.request(ts_method.upper(), url, headers=header, data=ts_api_body.encode('utf-8'))

        # 把返回值传递给前端页面
        response.encoding = "utf-8"
        return HttpResponse(response.text)
    except Exception as e:
        return HttpResponse(str(e))


# 获取主页请求记录
def get_home_log(request):
    user = request.session["user"]
    user_id = UserInfo.objects.filter(username=user)[0].id
    all_logs = DB_apis_log.objects.filter(user_id=user_id)
    ret = {"all_logs": list(all_logs.values("id", "api_method", 'api_host', 'api_url'))[::-1]}
    print(ret)
    return HttpResponse(json.dumps(ret), content_type='application/json')


# 获取主页请求接口记录
def get_api_log_home(request):
    user_id = request.GET.get('id')
    print(user_id)

    log = DB_apis_log.objects.filter(user_id=user_id)
    print(f"log======》》》》{log}")
    ret = {"log": list(log.values())[0]}
    # print(f" api_log_home ==>{ret}")  # ret 为一个json格式的字典，dumps后前端eval再进行取值
    return HttpResponse(json.dumps(ret), content_type='application/json')


# 进入用例库
def open_cases(request, id):
    project_id = id
    return render(request, 'welcome.html', {'whichHTML': 'P_cases.html', 'oid': project_id, **globaldict(request)})


# 新增大用例
def add_case(request, eid):
    DB_cases.objects.create(project_id=eid, name='新增待设置用例', creater=request.session['user'])
    return redirect('/cases/%s' % eid)


# 删除大用例
def del_case(request, eid, oid):
    DB_cases.objects.filter(id=oid).delete()
    DB_step.objects.filter(Case_id=oid).delelte()
    return redirect('/cases/%s' % eid)


# 复制大用例
def copy_case(request, eid, oid):
    old_case = DB_cases.objects.filter(id=oid)[0]
    DB_cases.objects.create(project_id=old_case.project_id, name=old_case.name + '_副本')
    return redirect('/cases/%s' % eid)


# 查询小用例数据
def get_small(request):
    case_id = request.GET.get("case_id")
    steps = DB_step.objects.filter(Case_id=case_id).order_by('index')
    ret = {"all_steps": list(steps.values("id", 'name', 'index'))}
    return JsonResponse(ret)


# mock
import demjson


def mock(request, interface):
    if request.method == "GET":
        path = request.path
        path = path.split("/")

        path = path[2:]
        path = "/" + "/".join(path)
        # print(path)
        # 获取本次请求的路径，不是数据库里存的路径
        route = Interface.objects.filter(interface_url=path)
        # print(route)

        if route:

            obj = Scene.objects.filter(id=1)[0]
            # print(f"数据库里存的请求头是{obj.request_head}")
            # print(f"数据库里存的响应结果是{obj.response_result}")
            # print(f"数据库里存的请求头是{obj.request_parameter}")

            # 如果数据库里存在这个路径
            headers = request.headers
            # 获取本次请求的请求头，不是数据库里存的请求头
            headers = demjson.decode(str(headers))
            headers = demjson.encode(headers)
            # print(f"headers 是{headers}")
            # params = request.GET.dict()
            # 获取本次请求的请求参数，不是数据库里存的请求参数
            # print(f"params 是{params} ")
            # params = json.dumps(params, separators=(",", ":"))

            obj = Scene.objects.get(
                # request_head__gte=headers,
                # request_parameter=params,
            )

            print(obj)
            print(obj.response_result)

            return HttpResponse(
                obj.response_result,
                content_type="application/json;charset=UTF-8"
            )
        else:
            return HttpResponse("请求的接口不存在！请检查路径是否正确！")

    if request.method == "POST":
        path = request.path
        # 获取本次请求的路径，不是数据库里存的路径
        route = Interface.objects.filter(interface_url=path)

        if route:
            # 如果数据库里存在这个路径
            headers = request.headers
            # 获取本次请求的请求头，不是数据库里存的请求头
            headers = demjson.decode(str(headers))
            headers = demjson.encode(headers)
            params = request.GET.dict()
            # 获取本次请求的请求参数，不是数据库里存的请求参数
            params = json.dumps(params, separators=(",", ":"))
            body = request.body.decode("utf-8")
            # 获取本次请求的请求体，不是数据库里存的请求体
            body = re.sub("\n|\t| ", "", body)
            # 去除换行、tab与空格

            obj = Scene.objects.get(

                request_head__gte=headers,
                request_parameter=params,
                request_body=body,
            )

            return HttpResponse(
                obj.response_result,
                content_type="application/json;charset=UTF-8"
            )
        else:
            return HttpResponse("请求的接口不存在！请检查路径是否正确！")


# 上传图片
def user_upload(request):
    print("开始上传图片")
    file = request.FILES.get("fileUpload", None)  # 靠name获取上传的文件，如果没有，避免报错，设置成None

    if not file:
        return HttpResponseRedirect('/home/')  # 如果没有则返回到首页

    new_name = str(request.session["user"]) + '.png'  # 设置好这个新图片的名字
    destination = open("api_test/static/user_img/" + new_name, 'wb+')  # 打开特定的文件进行二进制的写操作
    for chunk in file.chunks():  # 分块写入文件
        destination.write(chunk)
    destination.close()
    print("结束上传图片")
    return HttpResponseRedirect('/home/')  # 返回到首页


# 新增小用例步骤
def add_new_step(request):
    Case_id = request.GET.get("Case_id")
    # 通过这步控制新增步骤的index
    all_steps = len(DB_step.objects.filter(Case_id=Case_id))
    DB_step.objects.create(Case_id=Case_id, name='我是新步骤，请填写步骤内容', index=all_steps + 1)
    return HttpResponse("")


#  删除小用例步骤
def delete_step(request, eid):
    # step_id = eid
    step = DB_step.objects.filter(id=eid)[0]
    # 获取目标index
    index = step.index
    # 获取目标所属大用例case_id
    Case_id = step.Case_id
    # 删除目标step
    step.delete()

    for i in DB_step.objects.filter(Case_id=Case_id).filter(index__gt=index):
        i.index -= 1  # 执行顺序自减一
        i.save()  # 保存修改后的model对象

    return HttpResponse("")


# 小用例步骤获取数据
def get_step(request):
    step_ip = request.GET.get("step_id")
    print(f"step_id 是{step_ip}")
    step = DB_step.objects.filter(id=step_ip)
    steplist = list(step.values())[0]
    return HttpResponse(json.dumps(steplist), content_type='application/json')


# 小用例数据保存
def save_step(request):
    step_id = request.GET['step_id']
    name = request.GET['name']
    index = request.GET['index']
    step_method = request.GET['step_method']
    step_url = request.GET['step_url']
    step_host = request.GET['step_host']
    step_header = request.GET['step_header']
    step_body_method = request.GET['step_body_method']
    step_api_body = request.GET['step_api_body']
    ts_project_headers = request.GET.get('ts_project_headers')
    # 登录态
    step_login = request.GET.get("step_login")
    get_path = request.GET["get_path"]
    get_zz = request.GET["get_zz"]
    assert_zz = request.GET["assert_zz"]
    assert_path = request.GET["assert_path"]
    assert_qz = request.GET["assert_qz"]
    mock_res = request.GET['mock_res']
    DB_step.objects.filter(id=step_id).update(name=name,
                                              index=index,
                                              api_method=step_method,
                                              api_url=step_url,
                                              api_host=step_host,
                                              api_header=step_header,
                                              api_body_method=step_body_method,
                                              api_body=step_api_body,
                                              assert_qz=assert_qz,
                                              assert_path=assert_path,
                                              assert_zz=assert_zz,
                                              get_path=get_path,
                                              get_zz=get_zz,
                                              mock_res=mock_res,
                                              public_header=ts_project_headers,
                                              api_login=step_login
                                              )
    return HttpResponse("")


# select框获取数据
def step_get_api(request):
    api_id = request.GET.get('api_id')
    api = DB_apis.objects.filter(id=api_id).values()[0]
    return JsonResponse(api)


# 运行大用例
def Run_Case(request):
    Case_id = request.GET.get("Case_id")
    Case = DB_cases.objects.filter(id=Case_id)[0]
    steps = DB_step.objects.filter(Case_id=Case_id)

    from api_test.run_case import run
    run(Case_id, Case.name, steps)
    return HttpResponse("")


# 查看报告
def look_report(request, eid):
    Case_id = eid

    return render(request, 'Reports/%s.html' % Case_id)


# 上传fiddler文件
def upload_fd(request, Pid):
    print("开始文件上传")
    file = request.FILES.get("fileUpload", None)  # 靠name获取上传的文件，如果没有，避免报错，设置成None

    # if not file:
    #     return HttpResponseRedirect('/home/')  # 如果没有则返回到首页

    new_name = str(request.session["user"]) + '.txt'  # 设置好这个新图片的名字
    fd_file_dir = "api_test/static/fd_file/%s" % new_name
    destination = open(fd_file_dir, 'wb+')  # 打开特定的文件进行二进制的写操作

    for chunk in file.chunks():  # 分块写入文件
        destination.write(chunk)
    destination.close()
    print("结束文件上传")
    f = FidToSave(fd_file_dir)
    f.start()
    f.headers = json.dumps(f.headers)
    print(f" f.url===>{f.url}")
    DB_apis.objects.create(api_method=f.method.lower(),
                           api_url=f.url,
                           api_header=f.headers,
                           api_host=f.host,
                           body_method=f.data_method,
                           api_body=f.data,
                           name='fiddler导包待修改',
                           project_id_id=Pid)

    return redirect('/apis/%s/' % Pid)


# 全局请求头
def save_project_header(request):
    project_id = request.GET.get("project_id")
    req_names = request.GET.get("req_names")
    req_keys = request.GET.get("req_keys")
    req_values = request.GET.get("req_values")
    req_ids = request.GET["req_ids"]
    # print("全局请求头")
    print(f"req_names===>{req_names}")

    names = req_names.split(",")
    keys = req_keys.split(",")
    values = req_keys.split(",")
    ids = req_ids.split(",")

    # 当前端有空行时删除
    for i in range(len(ids)):
        if names[i] != '':
            if ids[i] == 'new':
                DB_project_header.objects.create(project_id=project_id, name=names[i], key=keys[i], value=values[i])
            else:
                DB_project_header.objects.filter(id=ids[i]).update(name=names[i], key=keys[i], value=values[i])
        else:
            try:

                DB_project_header.objects.filter(id=ids[i]).delete()
            except:
                pass
    # for i in range(len(names)):
    #     DB_project_header.objects.create(project_id=project_id,
    #                                      name=names[i],
    #                                      key=keys[i],
    #                                      value=values[i])

    return HttpResponse("")


def save_case_name(request):
    id = request.GET.get("id")
    name = request.GET.get("name")
    DB_cases.objects.filter(id=id).update(name=name)
    return HttpResponse('')


# 全局域名
def save_project_host(request):
    project_id = request.GET['project_id']
    req_names = request.GET['req_names']
    req_hosts = request.GET['req_hosts']
    req_ids = request.GET['req_ids']
    names = req_names.split(',')
    hosts = req_hosts.split(',')
    ids = req_ids.split(',')
    for i in range(len(ids)):
        if names[i] != '':
            if ids[i] == 'new':
                DB_project_host.objects.create(project_id=project_id, name=names[i], host=hosts[i])
            else:
                DB_project_host.objects.filter(id=ids[i]).update(name=names[i], host=hosts[i])
        else:
            try:
                DB_project_host.objects.filter(id=ids[i]).delete()
            except:
                pass
    return HttpResponse('')


# 获取项目登录态接口
def project_get_login(request):
    project_id = request.GET["project_id"]
    # print("project_id:",project_id)
    try:
        login = DB_login.objects.filter(project_id=project_id).values()[0]
    except:
        login = {}
    # print("login:",login)
    return HttpResponse(json.dumps(login), content_type='application/json')


# 登录态接口保存
def project_login_save(request):
    project_id = request.GET["project_id"]
    login_method = request.GET["login_method"]
    login_url = request.GET["login_url"]
    login_host = request.GET["login_host"]
    login_header = request.GET["login_header"]
    login_body_method = request.GET["login_body_method"]
    login_api_body = request.GET["login_api_body"]
    login_response_set = request.GET["login_response_set"]

    # 保存数据
    DB_login.objects.filter(project_id=project_id).update(
        api_method=login_method,
        api_url=login_url,
        api_header=login_header,
        api_host=login_host,
        body_method=login_body_method,
        api_body=login_api_body,
        set=login_response_set
    )
    # 返回
    return HttpResponse("success")


# 登录态接口请求
def project_login_send(request):
    # 第一步，获取前端数据
    login_method = request.GET['login_method']
    login_url = request.GET['login_url']
    login_host = request.GET['login_host']
    login_header = request.GET['login_header']
    login_body_method = request.GET['login_body_method']
    login_api_body = request.GET['login_api_body']
    login_response_set = request.GET['login_response_set']

    if login_header == "":
        ts_header = '{}'
    # 第二步，发送请求
    try:
        header = json.loads(login_header)  # 处理header
    except:
        return HttpResponse('请求头不符合json格式！')

    # 拼接完整url
    if login_host[-1] == '/' and login_url[0] == '/':  # 都有/
        url = login_host[:-1] + login_url
    elif login_host[-1] != '/' and login_url[0] != '/':  # 都没有/
        url = login_host + '/' + login_url
    else:  # 肯定有一个有/
        url = login_host + login_url
    try:
        if login_body_method == 'none':
            response = requests.request(login_method.upper(), url, headers=header, data={})
        elif login_body_method == 'form-data':
            files = []
            payload = {}
            for i in eval(login_api_body):
                payload[i[0]] = i[1]
            response = requests.request(login_method.upper(), url, headers=header, data=payload, files=files)

        elif login_body_method == 'x-www-form-urlencoded':
            header['Content-Type'] = 'application/x-www-form-urlencoded'
            payload = {}
            for i in eval(login_api_body):
                payload[i[0]] = i[1]
            response = requests.request(login_method.upper(), url, headers=header, data=payload)


        else:  # 这时肯定是raw的五个子选项：
            if login_body_method == 'Text':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'JavaScript':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'Json':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'Html':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'Xml':
                header['Content-Type'] = 'text/plain'
            response = requests.request(login_method.upper(), url, headers=header, data=login_api_body.encode('utf-8'))

        # 把返回值传递给前端页面
        response.encoding = "utf-8"
        DB_host.objects.update_or_create(host=login_host)
        res = response.json()

        # 第三步  对返回值进行提取
        #  判断是不是cookie持久化，不需要提取返回值
        if login_response_set == "cookie":

            end_res = {"response": response.text, "get_res": "cookie会话保持无需要提取返回值" }

        else:
            get_res = ""  # 声明提取结果存放
            for i in login_response_set.split("\n"):
                if i == "":
                    continue
                else:
                    i = i.replace(' ', '')
                    key = i.split('=')[0]  # 拿出key
                    path = i.split('=')[1]  # 拿出路径
                    value = res
                    for j in path.split('/')[1:]:
                        value = value[j]
                    get_res += key + '="' + value + '"\n'

                # 第四步，返回前端

            end_res = {"response": response.text, "get_res": get_res}

        return HttpResponse(json.dumps(end_res), content_type='application/json')

    except Exception as e:

        end_res = {"response": str(e), "get_res": ''}

        return HttpResponse(json.dumps(end_res), content_type='application/json')


# 调用登录态接口请求，数据从数据库中拿
# cookie持久化的时候 不需要提取返回值，只需要返回 持久化的a = requests.session() ，用于会话保持  return  a
def project_login_send_for_other(project_id):
    # 第一步，获取数据
    login_api= DB_login.objects.filter(project_id=project_id)[0]
    login_method = login_api.api_method
    login_url = login_api.api_url
    login_host = login_api.api_host
    login_header = login_api.api_header
    login_body_method = login_api.body_method
    login_api_body = login_api.api_body
    login_response_set = login_api.set

    if login_header == "":
        ts_header = '{}'

    # 第二步，发送请求
    try:
        header = json.loads(login_header) #处理header
    except:
        return HttpResponse('请求头不符合json格式！')

    # 拼接完整url
    if login_host[-1] == '/' and login_url[0] =='/': #都有/
        url = login_host[:-1] + login_url
    elif login_host[-1] != '/' and login_url[0] !='/': #都没有/
        url = login_host+ '/' + login_url
    else: #肯定有一个有/
        url = login_host + login_url
    try:
        if login_body_method == 'none':
            if login_response_set == 'cookie':
                print(f"login_response_set====>{login_response_set}")
                a = requests.Session()
                a.request(login_method.upper(), url, headers=header, data={})
                return a
            else:
                response = requests.request(login_method.upper(), url, headers=header, data={} )
        elif login_body_method == 'form-data':
            files = []
            payload = {}
            for i in eval(login_api_body):
                payload[i[0]] = i[1]
            if login_response_set == 'cookie':
                a = requests.Session()
                a.request(login_method.upper(), url, headers=header, data=payload, files=files)
                return a
            else:
                response = requests.request(login_method.upper(), url, headers=header, data=payload, files=files )

        elif login_body_method == 'x-www-form-urlencoded':
            header['Content-Type'] = 'application/x-www-form-urlencoded'
            payload = {}
            for i in eval(login_api_body):
                payload[i[0]] = i[1]
            if login_response_set == 'cookie':
                a = requests.Session()
                a.request(login_method.upper(), url, headers=header, data=payload )
                return a
            else:
                response = requests.request(login_method.upper(), url, headers=header, data=payload )


        else: #这时肯定是raw的五个子选项：
            if login_body_method == 'Text':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'JavaScript':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'Json':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'Html':
                header['Content-Type'] = 'text/plain'

            if login_body_method == 'Xml':
                header['Content-Type'] = 'text/plain'

            if login_response_set == 'cookie':
                a = requests.Session()
                a.request(login_method.upper(), url, headers=header, data=login_api_body.encode('utf-8'))
                return a
            else:
                response = requests.request(login_method.upper(), url, headers=header, data=login_api_body.encode('utf-8'))
        # 把返回值传递给前端页面
        response.encoding = "utf-8"
        DB_host.objects.update_or_create(host=login_host)
        res = response.json()
        # 第三步，对返回值进行提取
        get_res = {} #声明提取结果存放
        for i in login_response_set.split('\n'):
            if i == "":
                continue
            else:
                i = i.replace(' ','')
                key = i.split('=')[0] #拿出key
                path = i.split('=')[1]  #拿出路径
                value = res
                for j in path.split('/')[1:]:
                    value = value[j]
                get_res[key] = value
        return get_res
    except Exception as e:
        return {}




# 首页保存请求数据
def Home_save_api(request):
  project_id = request.GET['project_id']
  ts_method = request.GET['ts_method']
  ts_url = request.GET['ts_url']
  ts_host = request.GET['ts_host']
  ts_header = request.GET['ts_header']
  ts_body_method = request.GET['ts_body_method']
  ts_api_body = request.GET['ts_api_body']

  DB_apis.objects.create(project_id_id=project_id,
                         name = '首页保存接口,请给接口设置个名字吧！',
                         api_method = ts_method,
                         api_url = ts_url,
                         api_header = ts_header,
                         api_host = ts_host,
                         body_method = ts_body_method,
                         api_body = ts_api_body,
                         )

  return HttpResponse('')

#  主页搜索
def search(request):
    key = request.GET['key']

    # 项目名搜哦所
    projects = DB_project.objects.filter(name__contains=key) #获取name包含key的所有项目
    plist = [{"url":"/apis/%s/"%i.id,"text":i.name,"type":"project"} for i in projects]
    print(plist)
    # 接口名搜索
    apis = DB_apis.objects.filter(name__contains=key) #获取name包含key的所有接口
    alist = [{"url":"/apis/%s/"%i.project_id_id,"text":i.name,"type":"api"} for i in apis]
    print(alist)

    res = {"results":plist + alist}
    return HttpResponse(json.dumps(res),content_type='application/json')



def tools_json(request):

    return render(request, 'welcome.html', {"whichHTML": 'json.html', "oid": "", **globaldict(request)})


def compare_json(request):
    try:
        json1 = json.loads(request.GET.get("json1"))
        json2 = json.loads(request.GET.get("json2"))
    except:
        json1 = eval(request.GET.get("json1"))
        json2 = eval(request.GET.get("json2"))


    setattr(cj,"json_res",[])

    cj.compare_json_data(json1,json2)
    print(getattr(cj,"json_res"))
    print(type(getattr(cj,"json_res")))
    # return HttpResponse(getattr(cj,"json_res"))

    res_dic = {}
    for i in range(len(getattr(cj,"json_res"))):
        # print(i)
        res_dic[i+1] = getattr(cj,"json_res")[i]
    print(res_dic)

    return HttpResponse(json.dumps(res_dic),content_type="application/json")



def global_data(request,id):
    project_id = id

    return render(request, 'welcome.html', {"whichHTML": 'P_global_data.html', "oid": project_id, **globaldict(request)})
